import datetime

from django.db import models

from sportsground.utils.baseModels import BaseModels, IntegerChoices
from User.models import Msg, OrderYard, OrderVip, OrderGoods, OrderRent, UserVip, UserCoupon


class Order(BaseModels):
    class Meta():
        db_table = 'order'
        verbose_name = '订单'
        verbose_name_plural = verbose_name

    class OrderType(IntegerChoices):
        Yard = 1, "订场"
        Goods = 2, "商品"
        Rent = 3, "租赁"
        Vip = 4, "会员卡"

    class PayType(IntegerChoices):
        WX = 1, "微信支付"
        Balance = 2, "余额支付"

    oid = models.CharField(max_length=20, null=True, verbose_name="订单编号")
    user = models.ForeignKey(to="User", on_delete=models.CASCADE, verbose_name="用户")
    type = models.IntegerField(choices=OrderType.choices, verbose_name="商品类型")
    payTime = models.DateTimeField(null=True, verbose_name="支付时间")
    payType = models.IntegerField(null=True, choices=PayType.choices, verbose_name="支付方式")
    payCost = models.FloatField(null=True, verbose_name="实际花费")

    vipDerate = models.FloatField(null=True, verbose_name="vip抵扣")
    userVip = models.ForeignKey(to="User.UserVip", on_delete=models.SET_NULL, null=True, verbose_name="使用的会员卡")
    couponDerate = models.FloatField(null=True, verbose_name="优惠券抵扣")
    userCoupon = models.ForeignKey(to="User.UserCoupon", related_name="userCoupon", null=True,
                                   on_delete=models.SET_NULL,
                                   verbose_name="使用的优惠券")

    @classmethod
    def getOid(cls):
        today = datetime.date.today()
        oidL = f"{today.year}{today.month:02}{today.day:02}"
        order = cls.objects.last()
        if not order:  # 第一个
            oid = oidL + "0001"
        else:
            if order.oid[:8] == oidL:  # 当日有订单
                oid = f"{int(order.oid) + 1}"
            else:  # 当日首订单
                oid = oidL + "0001"
        return oid

    @classmethod
    def create(cls, user, venue, type):
        oid = cls.getOid()
        order = cls(oid=oid, user=user, type=type)
        order.save()
        Msg.create(user, f"【{venue.name}】您的订单还未支付，请及时支付。订单编号：{oid}")
        return order

    def Info(self):
        info = {
            "oid": self.oid,
            "type": self.type,
            "payTime": self.payTime,
            "payType": self.payType,
            "payCost": self.payCost,
            "vipDerate": self.vipDerate,
            "userVip": self.userVip.Info() if self.userVip else None,
            "couponDerate": self.couponDerate,
            "userCoupon":self.userCoupon.Info() if self.userCoupon else None,
            "createTime": self.createTime,
        }
        if self.type == self.OrderType.Yard:
            yard = self.orderyard_set.first()
            info['yard'] = yard.Info() if yard else None
        elif self.type == self.OrderType.Vip:
            vip = self.ordervip_set.first()
            info['vip'] = vip.Info() if vip else None
        elif self.type == self.OrderType.Goods:
            info['goods'] = []
            for item in self.ordergoods_set.all():
                info['goods'].append(item.Info())
        elif self.type == self.OrderType.Rent:
            info['rents'] = []
            for item in self.orderrent_set.all():
                info['rents'].append(item.Info())
        return info
        # 后续补充抵扣信息

    def canPay(self, payType, user, userVip=None, userCoupon=None):
        """ 是否能支付 """
        needPay = 0
        if userCoupon and not userCoupon.canPay(needPay):
            return False, "该优惠券不支持"
        if userVip and not userVip.vip.canPay(self.type):
            return False, "该会员卡不支持的类型"

        if self.type == self.OrderType.Yard:
            orderYard = self.orderyard_set.first()
            orderYard.checkTimeout()
            if orderYard.state != OrderYard.State.Paying:
                return False, "非支付状态"
            needPay += orderYard.price * orderYard.number
        elif self.type == self.OrderType.Vip:
            orderVip = self.ordervip_set.first()
            orderVip.checkTimeout()
            if orderVip.state != OrderVip.State.Paying:
                return False, "非支付状态"
            needPay += orderVip.price * orderVip.number
        elif self.type == self.OrderType.Goods:
            orderGoods = self.ordergoods_set.all()
            for item in orderGoods:
                item.checkTimeout()
                if item.state != OrderGoods.State.Paying:
                    return False, "非支付状态"
                needPay += item.price * item.number
        elif self.type == self.OrderType.Rent:
            orderRent = self.orderrent_set.all()
            for item in orderRent:
                item.checkTimeout()
                if item.state != OrderRent.State.Paying:
                    return False, "非支付状态"
                needPay += (item.price + item.rent.pledge) * item.number

        if payType == self.PayType.Balance:
            canBuy = user.balance
            if userCoupon:
                if not userCoupon.canUse(needPay):
                    return False, "该优惠券不支持"
                canBuy += userCoupon.coupon.derate

            if userVip:
                canBuy += userVip.value

            if needPay > canBuy:
                return False, "余额不足"
        self.needPay = needPay
        return True, ""

    def pay(self, user, payType, userVip=None, userCoupon=None):
        """ 支付 """
        needPay = self.needPay

        if userCoupon and userCoupon.canUse(needPay):
            needPay = userCoupon.cost(needPay)
            self.couponDerate = userCoupon.coupon.derate
            self.userCoupon = userCoupon
        if userVip and userVip.canUse(needPay):
            derate, needPay = userVip.cost(needPay)
            self.vipDerate = derate
            self.userVip = userVip
        self.payCost = needPay
        if payType == self.PayType.Balance:
            user.consume(needPay)

        self.payTime = datetime.datetime.now()
        self.payType = payType
        if self.type == self.OrderType.Yard:
            orderYard = self.orderyard_set.first()
            orderYard.pay()
        elif self.type == self.OrderType.Vip:
            orderVip = self.ordervip_set.first()
            orderVip.pay(user)
        elif self.type == self.OrderType.Goods:
            orderGoods = self.ordergoods_set.all()
            for item in orderGoods:
                item.pay()
        elif self.type == self.OrderType.Rent:
            orderRent = self.orderrent_set.all()
            for item in orderRent:
                item.pay()

        self.save()
        return True

    def drawback(self, id=None, message=''):
        """ 退款 """
        if self.type == self.OrderType.Yard:
            orderYard = self.orderyard_set.first()
            if orderYard.canDrawback():
                orderYard.orderDrawback(self.user, self.vipDerate, message)
                return True, ''

        elif self.type == self.OrderType.Goods:
            orderGoods = self.ordergoods_set.filter(id=id).first()
            if not orderGoods:
                return False, '未找到该商品'
            if orderGoods.canDrawback():
                orderGoods.orderDrawback(self.user, message)
                return True, ''

        elif self.type == self.OrderType.Rent:
            orderRent = self.orderrent_set.filter(id=id).first()
            if not orderRent:
                return False, '未找到该租赁'
            if orderRent.canDrawback():
                orderRent.orderDrawback(self.user,message)
                return True, ''
        return False, '无法退款'
